﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using YiNing.UI.Tools;

namespace YiNing.UI.Controls
{
    public class Die
    {
        [Category("可编辑参数")]
        [DisplayName("芯片标识")]
        [Description("可根据实际的芯片图谱添加")]
        /// <summary>
        /// 当前晶圆的标识
        /// </summary>
        public string Id { get; set; }

        /// <summary>
        /// 晶圆的程式名
        /// </summary>
        [Category("只读参数")]
        [ReadOnly(true)]
        public string ProgramName { get; set; }

        /// <summary>
        /// 检测次数
        /// </summary>
        [Category("只读参数")]
        [ReadOnly(true)]
        public int DetectNum { get; set; }
        public static Color[] DefaultColors = new Color[] { Color.DimGray, Color.Yellow, Color.Green, Color.Red, Color.Blue };

        /// <summary>
        /// 边沿颜色
        /// </summary>
        /// <returns></returns>
        [Category("只读参数")]
        [ReadOnly(true)]
        public const int DefaultEdge = 0;
        /// <summary>
        /// 获取默认状态下初始状态的id
        /// </summary>
        /// <returns></returns>
        [Category("只读参数")]
        [ReadOnly(true)]
        public const int DefaultUndo = 1;
        /// <summary>
        /// 获取默认状态下OK的id
        /// </summary>
        /// <returns></returns>
        [Category("只读参数")]
        [ReadOnly(true)]
        public const int DefaultOk = 2;
        /// <summary>
        /// 获取默认状态下Ng的id
        /// </summary>
        /// <returns></returns>
        [Category("只读参数")]
        [ReadOnly(true)]
        public const int DefaultNg = 3;
        /// <summary>
        /// 获取默认状态下未知的id
        /// </summary>
        /// <returns></returns>
        [Category("只读参数")]
        [ReadOnly(true)]
        public const int DefaultUnknown = 4;

        [Category("只读参数")]
        [ReadOnly(true)]
        private bool _enabled = false;
        /// <summary>
        /// 是否是边沿的die， 如果是，那么enabled必定是false
        /// </summary>
        [Category("只读参数")]
        [ReadOnly(true)]
        public bool IsEdge { get; set; }
        /// <summary>
        /// 是否有用的Die
        /// </summary>
        [Category("只读参数")]
        [ReadOnly(true)]
        public bool Enabled { get { if (IsEdge) return false; else return _enabled; } set { _enabled = value; } }
        /// <summary>
        /// 颜色Index
        /// </summary>
        [Category("只读参数")]
        [ReadOnly(true)]
        public int ColorIndex { get; set; }

        /// <summary>
        /// X序号
        /// </summary>
        [Category("只读参数")]
        [ReadOnly(true)]
        public int XIndex { get; set; }
        /// <summary>
        /// Y序号
        /// </summary>
        [Category("只读参数")]
        [ReadOnly(true)]
        public int YIndex { get; set; }
        /// <summary>
        /// X点的脉冲位置
        /// </summary>
        [Category("只读参数")]
        [ReadOnly(true)]
        public int XPluse { get; set; }
        /// <summary>
        /// Y点的脉冲位置
        /// </summary>
        [Category("只读参数")]
        [ReadOnly(true)]
        public int YPluse { get; set; }

        /// <summary>
        /// 芯片中心偏移晶圆中心的X脉冲
        /// </summary>
        [Category("只读参数")]
        [ReadOnly(true)]
        public int OffsetWaferCenterXPulse { get; set; }
        /// <summary>
        /// 芯片中心偏移晶圆中心的Y脉冲
        /// </summary>
        [Category("只读参数")]
        [ReadOnly(true)]
        public int OffsetWaferCenterYPulse { get; set; }

        /// <summary>
        /// 检测结果图和缺陷
        /// </summary>
        [Category("只读参数")]
        [ReadOnly(true)]
        public string Res { get; set; }
        /// <summary>
        /// 局部图
        /// </summary>
        public List<string> PartRes = new List<string>();
        /// <summary>
        /// 局部图类
        /// </summary>
        public List<PartResInfo> PartResInfos = new List<PartResInfo>();
        /// <summary>
        /// 当鼠标点击事件触发时，鼠标的参数
        /// </summary>
        [Category("只读参数")]
        [ReadOnly(true)]
        public MouseEventArgs MouseArgs { get; set; }


        #region 非标晶圆
        /// <summary>
        /// 知错图谱时候的晶圆中心点X
        /// </summary>
        [Category("只读参数")]
        [ReadOnly(true)]
        public int WaferCenterXPulse { get; set; }
        /// <summary>
        /// 制作图谱时候的晶圆中心点Y
        /// </summary>
        [Category("只读参数")]
        [ReadOnly(true)]
        public int WaferCenterYPulse { get; set; }
        [Category("只读参数")]
        [ReadOnly(true)]
        public double WaferRadius { get; set; }
        /// <summary>
        /// 制作图谱时候的芯片区域
        /// </summary>
        [Category("只读参数")]
        [ReadOnly(true)]
        public Quad DieQuad;
        #endregion

        #region 拼图的参数

        [Category("只读参数")]
        [ReadOnly(true)]
        public JigsawArgs JigsawArgs { get; set; }
        #endregion


        public string GetImagePath(string fileBaseName = "")
        {
            if (fileBaseName == "") fileBaseName = Res;
            return fileBaseName + ".jpg";
        }
        public string GetHobjPath(string fileBaseName = "")
        {
            if (fileBaseName == "") fileBaseName = Res;
            return fileBaseName + ".hobj";
        }

        public class PartResInfo
        {
            /// <summary>
            /// 局域网图片的地址
            /// </summary>
            public string ImageFileName { get; set; }

            /// <summary>
            /// 局部缺陷图在芯片大图中的位置
            /// </summary>
            public PointF ErrPointInDieImage { get; set; }
            /// <summary>
            /// 
            /// </summary>
            //public Rectangle Rectangle { get; set; }

        }


        #region 更新芯片坐标通过晶圆圆心
        /// <summary>
        /// 获取芯片左下角
        /// </summary>
        /// <param name="WaferCenter">圆心</param>
        /// <param name="dieWidth">芯片宽</param>
        /// <param name="dieHeight">芯片搞</param>
        /// <returns></returns>
        public Point GetDieRectLeftBottomPointByWaferCenter(Point WaferCenter, double dieWidth, double dieHeight)
        {
            return new Point(Convert.ToInt32(WaferCenter.X + OffsetWaferCenterXPulse - dieWidth / 2),
                Convert.ToInt32(WaferCenter.Y + OffsetWaferCenterYPulse - dieHeight / 2));
        }

        /// <summary>
        /// 获取芯片右上角点
        /// </summary>
        /// <param name="WaferCenter"></param>
        /// <param name="dieWidth"></param>
        /// <param name="dieHeight"></param>
        /// <returns></returns>
        public Point GetDieRectRightTopPointByWaferCenter(Point WaferCenter, double dieWidth, double dieHeight)
        {
            return new Point(Convert.ToInt32(WaferCenter.X + OffsetWaferCenterXPulse + dieWidth / 2),
                Convert.ToInt32(WaferCenter.Y + OffsetWaferCenterYPulse + dieHeight / 2));
        }

        /// <summary>
        /// 获取芯片左上角点
        /// </summary>
        /// <param name="WaferCenter"></param>
        /// <param name="dieWidth"></param>
        /// <param name="dieHeight"></param>
        /// <returns></returns>
        public Point GetDieRectLeftTopPointByWaferCenter(Point WaferCenter, double dieWidth, double dieHeight)
        {
            return new Point(Convert.ToInt32(WaferCenter.X + OffsetWaferCenterXPulse - dieWidth / 2),
                Convert.ToInt32(WaferCenter.Y + OffsetWaferCenterYPulse + dieHeight / 2));
        }

        /// <summary>
        /// 获取芯片右下角点
        /// </summary>
        /// <param name="WaferCenter"></param>
        /// <param name="dieWidth"></param>
        /// <param name="dieHeight"></param>
        /// <returns></returns>
        public Point GetDieRectRightBottomPointByWaferCenter(Point WaferCenter, double dieWidth, double dieHeight)
        {
            return new Point(Convert.ToInt32(WaferCenter.X + OffsetWaferCenterXPulse + dieWidth / 2),
                Convert.ToInt32(WaferCenter.Y + OffsetWaferCenterYPulse - dieHeight / 2));
        }
        #endregion



        #region 获取芯片制作图谱时候的坐标

        /// <summary>
        /// 获取芯片制作图谱时候的左下角
        /// </summary>
        /// <param name="offsetWaferLeftBottom">用于@获取左下角@</param>
        /// <param name="scaleX"></param>
        /// <param name="scaleY"></param>
        /// <param name="dieWidth"></param>
        /// <param name="dieHeight"></param>
        /// <returns></returns>
        public Point GetDieRectLeftBottomPoint(bool offsetWaferLeftBottom = false, double scaleX = 1, double scaleY = 1, double dieWidth = -1, double dieHeight = -1)
        {
            //scaleX = scaleY = 1;
            int tempXPulse = XPluse, tempYPulse = YPluse;
            if (offsetWaferLeftBottom)
            {
                tempXPulse = Convert.ToInt32(XPluse - (WaferCenterXPulse - WaferRadius));
                tempYPulse = Convert.ToInt32(YPluse - (WaferCenterYPulse - WaferRadius));
            }
            if (dieWidth == -1 && dieHeight == -1)
            {
                dieWidth = (DieQuad.MaxX - DieQuad.MinX) * scaleX;
                dieHeight = (DieQuad.MaxY - DieQuad.MinY) * scaleY;
            }
            return new Point(Convert.ToInt32(tempXPulse * scaleX - dieWidth / 2), Convert.ToInt32(tempYPulse * scaleY - dieHeight / 2));
        }

        /// <summary>
        /// 获取芯片制作图谱时候的右上角点
        /// </summary>
        /// <param name="WaferCenter"></param>
        /// <param name="dieWidth"></param>
        /// <param name="dieHeight"></param>
        /// <returns></returns>
        public Point GetDieRectRightTopPoint(bool offsetWaferLeftBottom = false, double scaleX = 1, double scaleY = 1, double dieWidth = -1, double dieHeight = -1)
        {
            int tempXPulse = XPluse, tempYPulse = YPluse;
            if (offsetWaferLeftBottom)
            {
                tempXPulse = Convert.ToInt32(XPluse - (WaferCenterXPulse - WaferRadius));
                tempYPulse = Convert.ToInt32(YPluse - (WaferCenterYPulse - WaferRadius));
            }
            if (dieWidth == -1 && dieHeight == -1)
            {
                dieWidth = (DieQuad.MaxX - DieQuad.MinX) * scaleX;
                dieHeight = (DieQuad.MaxY - DieQuad.MinY) * scaleY;
            }
            return new Point(Convert.ToInt32(tempXPulse * scaleX + dieWidth / 2),
                Convert.ToInt32(tempYPulse * scaleY + dieHeight / 2));
        }

        /// <summary>
        /// 获取芯片制作图谱时候的左上角点
        /// </summary>
        /// <param name="WaferCenter"></param>
        /// <param name="dieWidth"></param>
        /// <param name="dieHeight"></param>
        /// <returns></returns>
        public Point GetDieRectLeftTopPoint(bool offsetWaferLeftBottom = false, double scaleX = 1, double scaleY = 1, double dieWidth = -1, double dieHeight = -1)
        {
            int tempXPulse = XPluse, tempYPulse = YPluse;
            if (offsetWaferLeftBottom)
            {
                tempXPulse = Convert.ToInt32(XPluse - (WaferCenterXPulse - WaferRadius));
                tempYPulse = Convert.ToInt32(YPluse - (WaferCenterYPulse - WaferRadius));
            }
            if (dieWidth == -1 && dieHeight == -1)
            {
                dieWidth = (DieQuad.MaxX - DieQuad.MinX) * scaleX;
                dieHeight = (DieQuad.MaxY - DieQuad.MinY) * scaleY;
            }
            return new Point(Convert.ToInt32(tempXPulse * scaleX - dieWidth / 2),
                Convert.ToInt32(tempYPulse * scaleY + dieHeight / 2));
        }

        /// <summary>
        /// 获取芯片制作图谱时候的右下角点
        /// </summary>
        /// <param name="WaferCenter"></param>
        /// <param name="dieWidth"></param>
        /// <param name="dieHeight"></param>
        /// <returns></returns>
        public Point GetDieRectRightBottomPoint(bool offsetWaferLeftBottom = false, double scaleX = 1, double scaleY = 1, double dieWidth = -1, double dieHeight = -1)
        {
            int tempXPulse = XPluse, tempYPulse = YPluse;
            if (offsetWaferLeftBottom)
            {
                tempXPulse = Convert.ToInt32(XPluse - (WaferCenterXPulse - WaferRadius));
                tempYPulse = Convert.ToInt32(YPluse - (WaferCenterYPulse - WaferRadius));
            }
            if (dieWidth == -1 && dieHeight == -1)
            {
                dieWidth = (DieQuad.MaxX - DieQuad.MinX) * scaleX;
                dieHeight = (DieQuad.MaxY - DieQuad.MinY) * scaleY;
            }
            return new Point(Convert.ToInt32(tempXPulse * scaleX + dieWidth / 2),
                Convert.ToInt32(tempYPulse * scaleY - dieHeight / 2));
        }

        /// <summary>
        /// 获取芯片尺寸
        /// </summary>
        /// <returns></returns>
        public Size GetDieSize(double scaleX = 1, double scaleY = 1)
        {
            return new Size(Convert.ToInt32((DieQuad.MaxX - DieQuad.MinX) * scaleX), Convert.ToInt32((DieQuad.MaxY - DieQuad.MinY) * scaleY));
        }
        #endregion
    }

    public class JigsawArgs
    {
        /// <summary>
        /// x方向图片数量
        /// </summary>
        public int XPhotoNum { get; set; }
        /// <summary>
        /// y方向图片数量
        /// </summary>
        public int YPhotoNum { get; set; }
        /// <summary>
        /// x间距 机械间距
        /// </summary>
        public double IntervalX { get; set; }
        /// <summary>
        /// y间距 机械间距
        /// </summary>
        public double IntervalY { get; set; }
        /// <summary>
        /// 当前像元尺寸
        /// </summary>
        public double PixelLenght { get; set; }
        /// <summary>
        /// 拼图重叠区域默认0.1
        /// </summary>
        public double ScanFovCoverRatio { get; set; }
        /// <summary>
        /// 是否开启融合 0 表示开启，非0表示关闭
        /// </summary>
        public int FovJigsawFuse { get; set; }

        /// <summary>
        /// 局域网目录
        /// </summary>
        public string LanFilePath { get; set; }
        /// <summary>
        /// 要拼图的列表
        /// </summary>
        public List<string> ImageFileList { get; set; }

        public static JigsawArgs Default(int xAllFovNum, int yAllFovNum, double xInterval, double yInterval, double actualPixelLenght, double scanFovCoverRatio = 0.05, int fovJigsawFuse = 0)
        {
            return new JigsawArgs()
            {
                XPhotoNum = xAllFovNum,
                YPhotoNum = yAllFovNum,
                FovJigsawFuse = fovJigsawFuse,
                ImageFileList = new List<string>(),
                IntervalX = xInterval,
                IntervalY = yInterval,
                PixelLenght = actualPixelLenght,
                ScanFovCoverRatio = scanFovCoverRatio
            };
        }
    }
}
